#include "main.h"
#include "uart.h"
#include "led.h"
#include "key.h"
#include <stdio.h>
#include <stdlib.h>
#include "string.h"

char disp[20];	

struct Parking_Space{
	//int id;
	//int in_day;
	int hour;
	int min;
	int sec;
	int is_used;
};

struct Parking_Space parking[10];
int hour = 1,sec = 10,min = 25;
int parking_size=10;
int key_flag=0;
int id=0; 
int rate=1;		
int fee=0;

int in_enable = 0;
int out_enable = 0;	
char* tx_msg;

void SystemClock_Config(void);

void KEY_Control(void);		
void LCD_Control(void);	
void Led_Control(void);
void TIME_Control(void);
void UART_Control(void);

void In_Disp(void);
void Out_Disp(void);
void USART_Rate_Control(void);
void USART_Car_Control(void);

int Car_Control(int mode,int index_id);

int main(void)
{

  HAL_Init();
	
  SystemClock_Config();
	MX_USART1_Init();
	
	KEY_Init();
	LED_Init();
	LCD_Init();	
	
	LCD_Clear(White);
	LCD_SetBackColor(White);
	LCD_SetTextColor(Black);
	LED_Control(LED_ALL,0);
	
	for(int i = 0 ;i<10; i++){
		parking[i].is_used = 0;
	}
  while (1)
  {
		LCD_Control(); 	
		KEY_Control();	
		TIME_Control();	
		Led_Control();	
		UART_Control();	
  }
}


void SystemClock_Config(void){
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks 
  */
}



int Car_Control(int mode,int index_id){
	if(index_id < 1 || index_id > 10){
		return 0;
	}
	if(mode)
	{
		if(parking_size==0){
			return 0;
		}
		if(parking[index_id-1].is_used){
			return 0;
		}
		parking[index_id-1].hour = hour;
		parking[index_id-1].min  = min ;
		parking[index_id-1].sec  = sec ;
		parking[index_id-1].is_used  = 1;
		parking_size--;	
		return 1;
	}
	if(mode==0)
	{
		if(parking_size==10){
			return 0;
		}
		if(parking[index_id-1].is_used==0){
			return 0;
		}
		fee = (1 + hour - parking[index_id-1].hour)*rate;
		parking[index_id-1].is_used=0;
		parking_size++;
		return 1;
	}
	return 0;
}

void KEY_Control(){
	if(KEY_Scan()==1 && parking_size != 0)
	{
		id = 0;
		LCD_Clear(White);
		key_flag = 1;
		in_enable = 1;		
		Uart_SendString("Appoint a in Id\r\n");
	}
	if(KEY_Scan()==1 && parking_size == 0)
	{
		LED_Control(LED3,1);
		HAL_Delay(500);
		LED_Control(LED3,0);
	}
	if(KEY_Scan()==2)
	{
		id = 0;
		LCD_Clear(White);
		key_flag=2;
		out_enable = 1;
		Uart_SendString("Appoint a out Id\r\n");
	}
}

void USART_Car_Control(){
		int temp_id;
		if((UART1_Rx_Buf[3] - '0')== 0 && UART1_Rx_Buf[2] - '0'==1)
		{
				temp_id = 10;
		}
		else if(UART1_Rx_Buf[2] - '0' > 0 && UART1_Rx_Buf[3] - '0' <=9)
		{
				temp_id = UART1_Rx_Buf[2] - '0';
		}
		else{
				temp_id = 0;
		}
		if(key_flag==1)
		{
			if(!in_enable)
			{
				Uart_SendString("In_Key not press\r\n");
				return;
			}
			in_enable = 0;
			if(Car_Control(1,temp_id))
			{
				id = temp_id;
				sprintf(disp,"Park Success:ID%d\n",id);
				Uart_SendString(disp);
			}
			else
			{
				sprintf(disp,"Park Fail:ID%d\n",temp_id);
				Uart_SendString(disp);
			}
		}
		if(key_flag==2)
		{
			if(!out_enable)
			{
				Uart_SendString("Out_Key not press\r\n");
				return;
			}
			out_enable = 0;
			if(Car_Control(0,temp_id))
			{
				id = temp_id;
				sprintf(disp,"Go Out Success:ID%d\n",id);
				Uart_SendString(disp);
			}
			else
			{
				sprintf(disp,"Go Out Fail:ID%d\n",temp_id);
				Uart_SendString(disp);
			}
		}		
}

void USART_Rate_Control(){
		if((UART1_Rx_Buf[3] - '0')== 0 && UART1_Rx_Buf[2] - '0'==1)
		{
				rate = 10;
		}
		else if(UART1_Rx_Buf[2] - '0' > 0 && UART1_Rx_Buf[3] - '0' <=9)
		{
				rate = UART1_Rx_Buf[2] - '0';
		}
		else{
				rate = rate;
		}
}

void UART_Control(){
	if(UART1_Rx_flg==1)
	{
		if(UART1_Rx_Buf[0]=='I' && UART1_Rx_Buf[1]=='D')
		{
			USART_Car_Control();
		}
		else if(UART1_Rx_Buf[0]=='F' && UART1_Rx_Buf[1]=='x')
		{
			USART_Rate_Control();
		}
		else
		{
			Uart_SendString("Error Command\n");
		}
		for(int i = 0;i<UART1_Rx_cnt;i++){
			UART1_Rx_Buf[i] = '\0';
		}
    UART1_Rx_cnt = 0;
    UART1_Rx_flg = 0;
	}
}

void Led_Control(){
	if(parking_size!=0){
		LED_Control(LED2,0);
		LED_Control(LED1,1);
	}
	else{
		LED_Control(LED1,0);
		LED_Control(LED2,1);
	}
}


void TIME_Control(void){
	if(sec==60){
		sec=0;
		min+=1;
	}
	if(min==60){
		min=0;
		hour+=1;
	}
	if(hour==24)
		hour=0;
}

void In_Disp(){
	LCD_DisplayStringLine(Line2," ID Code    Time");
	if(id!=0){
		sprintf(disp,"   %d      %02d:%02d:%02d",id,parking[id-1].hour,parking[id-1].min,parking[id-1].sec);
	}else{
		sprintf(disp,"   %s      %02d:%02d:%02d","x",hour,min,sec);
	}
	LCD_DisplayStringLine(Line4,(u8 *)disp);
	sprintf(disp,"           Rates:%d",rate);
	LCD_DisplayStringLine(Line8,(u8 *)disp);
}


void Out_Disp(){
	LCD_DisplayStringLine(Line2," ID Code    Fee");
	if(id!=0){
		sprintf(disp,"   %d        %2d",id,fee);
	} else {
		sprintf(disp,"   %s        %2d","x",0);
	}
	
	LCD_DisplayStringLine(Line4,(u8 *)disp);
	sprintf(disp,"           Rates:%d",rate);
	LCD_DisplayStringLine(Line8,(u8 *)disp);
}


void LCD_Control(){
	if(key_flag==0){
		sprintf(disp,"           Rates:%d",rate);
		LCD_DisplayStringLine(Line8,(u8 *)disp);
	}
	if(key_flag==1){
		In_Disp();
	}
	if(key_flag==2){
		Out_Disp();
	}
}








void Error_Handler(void){}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line){ }
#endif
